#include "prec.h"
#include "artbutton.h"
#include "artpanel.h"
#include "wx/log.h"
#include "wx/dcbuffer.h"

IMPLEMENT_DYNAMIC_CLASS(ArtButton, wxControl)

BEGIN_EVENT_TABLE(ArtButton, wxControl)
	EVT_PAINT(ArtButton::OnPaint)
	EVT_ERASE_BACKGROUND(ArtButton::OnEraseBackground)
	EVT_SIZE(ArtButton::OnSize)
	EVT_LEFT_DOWN(ArtButton::OnLeftDown)
	EVT_LEFT_UP(ArtButton::OnLeftUp)
	EVT_LEAVE_WINDOW(ArtButton::OnMouseLeave)
	EVT_ENTER_WINDOW(ArtButton::OnMouseEnter)
	EVT_SET_FOCUS(ArtButton::OnGainFocus)
	EVT_KILL_FOCUS(ArtButton::OnLoseFocus)
	EVT_LEFT_DCLICK(ArtButton::OnLeftDown)
END_EVENT_TABLE()

ArtButton::ArtButton( ArtPanel *parent, wxWindowID id, 
								 const wxString& label,
								 const wxBitmap& bitmap, 
								 const wxPoint& pos /*= wxDefaultPosition*/, 
								 const wxSize& size /*= wxDefaultSize*/, 
								 long style /*= 0*/, 
								 const wxString& name /*= wxStaticTextNameStr*/ )
								 : wxControl(parent, id, pos, size, style | wxNO_BORDER, wxDefaultValidator, name)
								 , m_artPanel(parent)
{
	m_bitmap = bitmap;

	wxControl::SetLabel(label);
	InheritAttributes();
	SetInitialSize(size);
}

void ArtButton::SetBitmap( const wxBitmap& bitmap )
{
	m_bitmap = bitmap;
	Refresh();
}

void ArtButton::OnPaint( wxPaintEvent& event )
{
	wxBufferedPaintDC dc(this);

	dc.SetBackground(wxBrush(GetParent()->GetBackgroundColour()));
	dc.Clear();

 	wxBitmap bmp = m_artPanel->GetBackgroundRegion(GetId());
 	if (bmp.Ok())
 	{
 		dc.DrawBitmap(bmp, 0, 0, false);
 	}

	wxRect clientRect = GetClientRect();
	wxWindow* capture = wxWindow::GetCapture();

	int x = clientRect.x, y = clientRect.y, width = clientRect.width, height = clientRect.height;

	int shadowOffset;
	if (capture != this)
	{
		shadowOffset = 0;
		if (m_bgBitmap.Ok())
			dc.DrawBitmap(m_bgBitmap, 0, 0, true);
	}
	else
	{
		shadowOffset = 1;
		if (m_bgHoverBitmap.Ok())
			dc.DrawBitmap(m_bgHoverBitmap, 0, 0, true);
	}

	dc.SetFont(GetFont());
	dc.SetPen(wxPen(GetForegroundColour()));

	wxString label = GetLabel();
	wxSize tsize = dc.GetMultiLineTextExtent(label);
	int tw = tsize.x, th = tsize.y;
	int bw = 0, bh = 0;
	if (m_bitmap.Ok())
	{
		bw = m_bitmap.GetWidth();
		bh = m_bitmap.GetHeight();
	}

	int pos_x = (width-bw-tw)/2+shadowOffset;
	if (m_bitmap.Ok())
	{
		int pos_y =  (height-bh)/2+shadowOffset;
		dc.DrawBitmap(m_bitmap, pos_x, pos_y, true);
		pos_x = pos_x + 2;
	}

	dc.DrawLabel(label, wxRect(pos_x + bw + shadowOffset, (height-th)/2+shadowOffset, tw, th));
}

void ArtButton::OnSize( wxSizeEvent& event )
{
	event.Skip();
	Refresh();
}

void ArtButton::OnEraseBackground( wxEraseEvent& event )
{

}

wxSize ArtButton::DoGetBestSize() const
{
	wxString label = GetLabel();
	if (label.IsEmpty())
		return wxSize(112, 48);

	wxClientDC dc((wxWindow*)this);
	dc.SetFont(GetFont());
	wxSize size = dc.GetMultiLineTextExtent(label);

	int bmpWidth = 0, bmpHeight = 0;
	int constant = 15;
	if (m_bitmap.Ok())
	{
		bmpWidth = m_bitmap.GetWidth()+10;
		bmpHeight = m_bitmap.GetHeight();
		size.x += bmpWidth;
		size.y = size.y > bmpHeight ? size.y : bmpHeight;
		size.x += constant;
		size.y += constant;
	}

	wxSize bgsize(0,0);
	if (m_bgBitmap.Ok())
	{
		bgsize.SetWidth(m_bgBitmap.GetWidth());
		bgsize.SetHeight(m_bgBitmap.GetHeight());
	}

	if (bgsize.x > size.x)
		size.x = bgsize.x;
	if (bgsize.y > size.y)
		size.y = bgsize.y;

	return size;
}

void ArtButton::SetLabel( const wxString &label )
{
	wxControl::SetLabel(label);
	Refresh();
}

void ArtButton::OnLeftDown( wxMouseEvent& event )
{
	if(!IsEnabled())
		return;

	m_mouseAction = CLICK;
	CaptureMouse();
	Refresh();
	event.Skip();
}

void ArtButton::OnLeftUp( wxMouseEvent& event )
{
	if (!IsEnabled() || !HasCapture())
		return;

	wxPoint pos = event.GetPosition();
	wxRect rect = GetClientRect();

	if (HasCapture())
		ReleaseMouse();

	if (rect.Contains(pos))
	{
		m_mouseAction = HOVER;
		Notify();
	}
	else
	{
		m_mouseAction = 0;
	}

	Refresh();
	event.Skip();
}

void ArtButton::OnMouseLeave( wxMouseEvent& event )
{
	m_mouseAction = None;
	Refresh();
	event.Skip();
}

void ArtButton::OnMouseEnter( wxMouseEvent& event )
{
	if (!IsEnabled())
		return;

	m_mouseAction = HOVER;
	Refresh();
	event.Skip();
}

void ArtButton::OnGainFocus( wxFocusEvent& event )
{
	m_hasFocus = true;
	Refresh();
	Update();
}

void ArtButton::OnLoseFocus( wxFocusEvent& event )
{
	m_hasFocus = false;
	Refresh();
	Update();
}

bool ArtButton::AcceptsFocus() const
{
	return IsShown() && IsEnabled();
}

wxVisualAttributes ArtButton::GetDefaultAttributes() const
{
	return wxButton::GetClassDefaultAttributes();
}

bool ArtButton::Enable( bool enable /*= true*/ )
{
	bool ret = wxControl::Enable(enable);
	Refresh();
	return ret;
}

bool ArtButton::SetForegroundColour( const wxColour& colour )
{
	bool ret = wxControl::SetForegroundColour(colour);
	Refresh();
	return ret;
}

void ArtButton::SetDefault()
{

}

void ArtButton::Notify()
{
	ArtButtonEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
	evt.SetButtonObj(this);
	evt.SetEventObject(this);
	GetEventHandler()->ProcessEvent(evt);
}

void ArtButton::SetBackground( const wxBitmap& bitmap )
{
	if (bitmap.Ok())
	{
		m_bgBitmap = bitmap;
		Refresh();
	}
}

void ArtButton::SetBackgroundHover( const wxBitmap& bitmap )
{
	if (bitmap.Ok())
	{
		m_bgHoverBitmap = bitmap;
		if (m_mouseAction != None)
			Refresh();
	}
}